<?php
/**
 * Created by PhpStorm.
 * User: zcq
 * Date: 2019/7/29
 * Time: 9:52
 */

namespace app\common;


use think\Exception;
use traits\think\Instance;

class Sms
{
    use Instance;
    //限制10分钟发送手机的次数和ip次数
    public $time_limit = 10; //分钟
    public $phone_limit = 3;
    public $ip_limit = 10;

    private function __construct()
    {

    }


    public function send_code($phone,$minute = 3)
    {
        //发送短信接口限制
        if(!$this->tries_limit($phone)){
            return dataReturn(0,'发送短信次数过多，请稍后再试');
        }
        $cache_key = 'code_'.$phone;
        if(env("SMS_DEMO",false)){
            //测试验证码
            $res = true;
            $new_code = 1234;
        }else{
            //发送真实验证码
            $new_code = mt_rand(1000,9999);
            $info = "您的验证码为".$new_code."，请在收到后的".$minute."分钟内使用。【四川观察】";
            $res = $this->chanzor($phone,$info);
        }

        $expire_time = $minute*60;
        if($res){
            RedisCache::getInstance()->cache($cache_key,$new_code,$expire_time);
            $this->save_limit($phone);
            return dataReturn(1,'发送短信成功');
        }
        return dataReturn(0,'发送短信失败，请稍后再试');
    }

    public function validate($phone,$code)
    {
        $cache_key = 'code_'.$phone;

        if($code){
            $old_code = RedisCache::getInstance()->cache($cache_key);
            if(!$old_code || $old_code != $code)
                return false;
//                return dataReturn(0,'验证码不正确');

            RedisCache::getInstance()->cache($cache_key,null);
            return true;
        }
        return false;
    }

    /**
     * @param $phone
     * 发送短信成功，缓存发送数据
     */
    public function save_limit($phone)
    {
        $ip = request()->ip();
        //根据手机号和ip限制短信数量
        $phone_key = 'phone_limit_'.$phone;
        $ip_key = 'ip_limit_'.$ip;
        $res1 = $this->base_save_limit($phone_key);
        $res2 = $this->base_save_limit($ip_key);
    }

    public function base_save_limit($redis_key)
    {
        $json = RedisCache::getInstance()->cache($redis_key);
        if($json){
           $data = json_decode($json,1);
        }
        if(empty($data))
            $data = [];

        $data[] = time();

        $data_json = json_encode($data,JSON_UNESCAPED_UNICODE);
        $expire_time = $this->time_limit*60;

        $res = RedisCache::getInstance()->cache($redis_key,$data_json,$expire_time);
        return $res;
    }

    /**
     * @param $phone
     * 检查短信发送次数
     */
    public function tries_limit($phone)
    {
        $ip = request()->ip();
        //根据手机号和ip限制短信数量
        $phone_key = 'phone_limit_'.$phone;
        $ip_key = 'ip_limit_'.$ip;

        $res1 = $this->validate_limit($phone_key,$this->phone_limit);
        if(!$res1)
            return false;

        $res2 = $this->validate_limit($ip_key,$this->ip_limit);
        if(!$res2)
            return false;

        return true;
    }

    private function validate_limit($redis_key,$limit)
    {
        $json = RedisCache::getInstance()->cache($redis_key);
        if(!$json)
            return true;

        $data = json_decode($json,1);
        $time = time();
        $limit_seconds = $this->time_limit*60;
        $nums = 0;
        foreach ($data as $v){
            if($time - $v < $limit_seconds)
                $nums++;

            //超出发送次数
            if($nums >= $limit)
                return false;
        }
        return true;
    }

    /**
     * @param $phone
     * @param $code
     * @param $minute
     * 畅卓发送短信
     */
    public function chanzor($phone,$info)
    {
        $target = "http://sms.chanzor.com:8001/sms.aspx";
        $account = config('setting.sms_key');
        $password = config('setting.sms_secret');
        //替换成自己的测试账号,参数顺序和wenservice对应
        $post_data = "action=send&account=".$account."&password=".$password."&mobile=".$phone."&content=".rawurlencode($info);
        $res = creat_curl($target,$post_data);
        if(!$res)
            return false;

        $res = xmlstr_to_array($res);
        if(isset($res['returnstatus']) && $res['returnstatus'] == 'Success'){
            return true;
        }

        return false;
    }

    /**
     * @param $phoneNumbers
     * @param null $code
     * @param int $expire_time
     * @return string
     * 腾讯发送短信
     */
    public function tencent_sms($phoneNumbers,$code = null,$expire_time = 5)
    {
        $config = config('wechat.tencent_sms');
        $appid = $config['AppID'];
        $appkey = $config['Key'];
        $templateId = $config['template_id'];
        $cache_key = 'code_'.$phoneNumbers;

        if($code){
            $old_code = cache($cache_key);
            if(!$old_code || $old_code != $code){
                return dataReturn(0,'验证码不正确');
            }
            cache($cache_key,null);
            return dataReturn(1,'验证码正确');
        }
        $code = mt_rand(1000,9999);
        $params= ["$code","$expire_time"];
        try {
            $ssender = new SmsSingleSender($appid, $appkey);
//            $params = ["5678"];
            $result = $ssender->sendWithParam("86", $phoneNumbers, $templateId,
                $params, '', "", "");  // 签名参数未提供或者为空时，会使用默认签名发送短信
            $rsp = json_decode($result,1);

        } catch(\Exception $e) {
            return dataReturn(0,'发送失败1');
        }
        if(!$rsp['result']){
            cache($cache_key,$code,$expire_time*60);
            return dataReturn(1,'发送成功');
        }
        return dataReturn(0,'发送失败2');
    }
}